home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / kiss.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  5KB  |  226 lines

  1. /* Routines for AX.25 encapsulation in KISS TNC
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Modified by G1EMM 19/11/90 to support multi-port KISS mode. 
  5.  */
  6.  /* Mods by G1EMM */
  7.  
  8. #include "global.h"
  9. #include "mbuf.h"
  10. #include "iface.h"
  11. #include "kiss.h"
  12. #include "devparam.h"
  13. #include "slip.h"
  14. #include "asy.h"
  15. #include "ax25.h"
  16. #include "pktdrvr.h"
  17.  
  18. /* Send raw data packet on KISS TNC */
  19. int
  20. kiss_raw(iface,data)
  21. struct iface *iface;
  22. struct mbuf *data;
  23. {
  24.     register struct mbuf *bp;
  25.  
  26.     /* Put type field for KISS TNC on front */
  27.     if((bp = pushdown(data,1)) == NULLBUF){
  28.         free_p(data);
  29.         return -1;
  30.     }
  31.     bp->data[0] = PARAM_DATA;
  32.     bp->data[0] |= (iface->port << 4);
  33.     if(iface->port){
  34.         iface->rawsndcnt++;
  35.         iface->lastsent = secclock();
  36.     }
  37.     /* slip_raw also increments sndrawcnt */
  38.     slip_raw(Slip[iface->xdev].iface,bp);
  39.     return 0;
  40. }
  41.  
  42. /* Process incoming KISS TNC frame */
  43. void
  44. kiss_recv(iface,bp)
  45. struct iface *iface;
  46. struct mbuf *bp;
  47. {
  48.     char kisstype;
  49.     struct iface *kissif;
  50.     int port;
  51.  
  52.     kisstype = PULLCHAR(&bp);
  53.     port = kisstype >> 4;
  54.  
  55.     if((kissif = Slip[iface->xdev].kiss[port]) == NULLIF){
  56.         free_p(bp);
  57.         return;
  58.     }    
  59.  
  60.     switch(kisstype & 0xf){
  61.     case PARAM_DATA:
  62.         ax_recv(kissif,bp);
  63.         break;
  64.     default:
  65.         free_p(bp);
  66.         break;
  67.     }
  68. }
  69. /* Perform device control on KISS TNC by sending control messages */
  70. int32
  71. kiss_ioctl(iface,cmd,set,val)
  72. struct iface *iface;
  73. int cmd;
  74. int set;
  75. int32 val;
  76. {
  77.     struct mbuf *hbp;
  78.     char *cp;
  79.     int32 rval = 0L;
  80.  
  81.     /* At present, only certain parameters are supported by
  82.      * stock KISS TNCs. As additional params are implemented,
  83.      * this will have to be edited
  84.      */
  85.     switch(cmd){
  86.     case PARAM_RETURN:
  87.     case PARAM_RETURN2:
  88.         set = 1;    /* Note fall-thru */
  89.     case PARAM_TXDELAY:
  90.     case PARAM_PERSIST:
  91.     case PARAM_SLOTTIME:
  92.     case PARAM_TXTAIL:
  93.     case PARAM_FULLDUP:
  94.     case PARAM_HW:
  95.         if(!set){
  96.             rval = -1;    /* Can't read back */
  97.             break;
  98.         }
  99.         /* Allocate space for cmd and arg */
  100.         if((hbp = alloc_mbuf(2)) == NULLBUF){
  101.             free_p(hbp);
  102.             rval = -1;
  103.             break;
  104.         }
  105.         cp = hbp->data;
  106.         *cp++ = cmd;
  107.         *cp = val;
  108.         hbp->cnt = 2;
  109.         if(hbp->data[0] != (char) PARAM_RETURN)
  110.             hbp->data[0] |= (iface->port << 4);
  111.         if(iface->port){
  112.             iface->rawsndcnt++;
  113.             iface->lastsent = secclock();
  114.         }
  115.         /* Even more "raw" than kiss_raw */
  116.         slip_raw(Slip[iface->xdev].iface,hbp);
  117. /*        slip_raw(iface,hbp);    / * Even more "raw" than kiss_raw */
  118.         rval = val;
  119.         break;
  120.     case PARAM_SPEED:    /* These go to the local asy driver */
  121.     case PARAM_DTR:
  122.     case PARAM_RTS:
  123.     case PARAM_UP:
  124.     case PARAM_DOWN:
  125. #ifdef UNIX
  126.     case PARAM_MIN:        /* almost certainly not its intended use... */
  127. #endif
  128.         rval = asy_ioctl(iface,cmd,set,val);
  129.         break;
  130.     default:        /* Not implemented */
  131.         rval = -1;
  132.         break;
  133.     }
  134.     return rval;
  135. }
  136.  
  137. int
  138. #ifdef PROTOTYPES
  139. kiss_stop(struct iface *iface)
  140. #else
  141. kiss_stop(iface)
  142. struct iface *iface;
  143. #endif
  144. {
  145.     Slip[iface->xdev].kiss[iface->port] = NULLIF;
  146.     return 0;
  147. }
  148.  
  149. /* Attach a kiss interface to an existing asy interface in the system
  150.  * argv[0]: hardware type, must be "kiss"
  151.  * argv[1]: master interface, e.g., "ax4"
  152.  * argv[2]: kiss port, e.g., "4"
  153.  * argv[3]: interface label, e.g., "ax0"
  154.  * argv[4]: maximum transmission unit, bytes
  155.  */
  156. int
  157. #ifdef PROTOTYPES
  158. kiss_attach(int argc,char **argv,void *p)
  159. #else
  160. kiss_attach(argc,argv,p)
  161. int argc;
  162. char *argv[];
  163. void *p;
  164. #endif
  165. {
  166.     struct iface *if_asy, *if_kiss;
  167.     int port;
  168.  
  169.     if((if_asy = if_lookup(argv[1])) == NULLIF){
  170.         tprintf("Interface %s does not exist\n",argv[1]);
  171.         return -1;
  172.     }
  173.  
  174.     /* Check for ASY type interface ! - WG7J */
  175.     if(if_asy->type != CL_AX25) {
  176.         tprintf("Multidrop KISS not allowed in interface: %s\n",argv[1]);
  177.         return -1;
  178.     }
  179.  
  180.     if(if_lookup(argv[3]) != NULLIF){
  181.         tprintf("Interface %s already exists\n",argv[4]);
  182.         return -1;
  183.     }
  184.  
  185.     if((port = atoi(argv[2])) == 0){
  186.         tprintf("Port 0 automatically assigned to interface %s\n",argv[1]);
  187.         return -1;
  188.     }
  189.  
  190.     if(port < 1 || port > 15){
  191.         tprintf("Ports 1 to 15 only\n");
  192.         return -1;
  193.     }
  194.  
  195.     if(Slip[if_asy->xdev].kiss[port] != NULLIF){
  196.         tprintf("Port %d already allocated on interface %s\n", port, argv[1]);
  197.         return -1;
  198.     }
  199.     /* Create interface structure and fill in details */
  200.     if_kiss = (struct iface *)callocw(1,sizeof(struct iface));
  201.     if_kiss->addr = if_asy->addr;
  202.     if_kiss->name = strdup(argv[3]);
  203.  
  204.     if(argc >= 5){
  205.         if_kiss->mtu = atoi(argv[4]);
  206.     } else {
  207.         if_kiss->mtu = if_asy->mtu;
  208.     }
  209.  
  210.     if_kiss->dev = if_asy->dev;
  211.     if_kiss->stop = kiss_stop;
  212.     setencap(if_kiss,"AX25");
  213.     if_kiss->ioctl = kiss_ioctl;
  214.     if_kiss->raw = kiss_raw;
  215.     if(if_kiss->hwaddr == NULLCHAR)
  216.         if_kiss->hwaddr = mallocw(AXALEN);
  217.     memcpy(if_kiss->hwaddr,Mycall,AXALEN);
  218.     if_kiss->xdev = if_asy->xdev;
  219.     if_kiss->next = Ifaces;
  220.     Ifaces = if_kiss;
  221.     if_kiss->port = port;
  222.     Slip[if_kiss->xdev].kiss[if_kiss->port] = if_kiss;
  223.     return 0;
  224. }
  225.  
  226.